package com.zb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.entity.OrderGoodsCodeVo;
import com.zb.entity.ZjWorkGoods;
import com.zb.entity.ZjWorkGoodsCode;
import com.zb.extend.WorkGoodsExtend;
import com.zb.mapper.ZjWorkGoodsMapper;
import com.zb.service.ViewGoodsService;
import com.zb.service.ZjWorkGoodsCodeService;
import com.zb.service.ZjWorkGoodsService;
import com.zb.view.ViewGoods;
import com.zb.vo.OrderGoodsVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 工单商品表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-09-20
 */
@Service
public class ZjWorkGoodsServiceImpl extends ServiceImpl<ZjWorkGoodsMapper, ZjWorkGoods> implements ZjWorkGoodsService {
    @Resource
    ZjWorkGoodsMapper workGoodsMapper;
    @Resource
    private ZjWorkGoodsCodeService workGoodsCodeService;
    @Resource
    private ViewGoodsService viewGoodsService;

    // 新增、修改、删除工单商品
    @Override
    public void save(Long custAccId, Long workId, List<OrderGoodsVo> orderGoodsVos, List<Long> delOrderGoodsIds) {
        if (null != delOrderGoodsIds && !delOrderGoodsIds.isEmpty()) {
            workGoodsCodeService.deleteBatchByWorkGoodsIds(delOrderGoodsIds);
            this.removeByIds(delOrderGoodsIds);
        }
        Assert.isTrue(null != orderGoodsVos && !orderGoodsVos.isEmpty(), "工单商品不能为空，至少填写一项");
        // 合并相同商品
        List<OrderGoodsVo> orderGoodsVoList = new ArrayList<>();
        orderGoodsVos.forEach(t -> {
            if (orderGoodsVoList.stream().anyMatch(vo -> Objects.equals(vo.getGoodsId(), t.getGoodsId()) && Objects.equals(vo.getGoodsSpecId(), t.getGoodsSpecId())
                    && Objects.equals(DateUtil.format(t.getBuyTime(), "yyyy-MM-dd"), DateUtil.format(vo.getBuyTime(), "yyyy-MM-dd"))
                    && Objects.equals(DateUtil.format(t.getEndTime(), "yyyy-MM-dd"), DateUtil.format(vo.getEndTime(), "yyyy-MM-dd")))) {
                orderGoodsVoList.forEach(vo -> {
                    if (Objects.equals(vo.getGoodsId(), t.getGoodsId()) && Objects.equals(vo.getGoodsSpecId(), t.getGoodsSpecId())
                            && Objects.equals(DateUtil.format(t.getBuyTime(), "yyyy-MM-dd"), DateUtil.format(vo.getBuyTime(), "yyyy-MM-dd"))
                            && Objects.equals(DateUtil.format(t.getEndTime(), "yyyy-MM-dd"), DateUtil.format(vo.getEndTime(), "yyyy-MM-dd"))) {
                        vo.getGoodsCodes().addAll(t.getGoodsCodes());
                    }
                });
            } else {
                orderGoodsVoList.add(t);
            }
        });

        // 获取已存在的工单商品
        List<ZjWorkGoods> goodsList = workGoodsMapper.getByWorkId(workId);
        List<Long> workGoodsIds = goodsList.stream().map(ZjWorkGoods::getId).toList();
        List<ZjWorkGoodsCode> workGoodsCodeList = workGoodsCodeService.getByWorkGoodsIds(workGoodsIds);
        orderGoodsVoList.forEach(t -> {
            ZjWorkGoods workGoods = goodsList.stream().filter(goods -> Objects.equals(t.getGoodsId(), goods.getGoodsId()) && Objects.equals(t.getGoodsSpecId(), goods.getGoodsSpecId())).findFirst().orElse(null);
            if (null != workGoods) {
                t.setId(workGoods.getId());
                t.getGoodsCodes().addAll(workGoodsCodeList.stream().filter(workGoodsCode -> Objects.equals(workGoodsCode.getWorkGoodsId(), t.getId())).map(code -> {
                    return new OrderGoodsCodeVo(code.getCodeId(), code.getCode());
                }).toList());
            }
        });

        List<ZjWorkGoods> adds = new ArrayList<>();
        List<ZjWorkGoods> updates = new ArrayList<>();
        ZjWorkGoods goods = null;
        List<ZjWorkGoodsCode> goodsCodes = new ArrayList<>();
        List<Long> workGoodsId = new ArrayList<>();
        ZjWorkGoodsCode goodsCode = null;
        for (OrderGoodsVo vo : orderGoodsVoList) {
            // 编码去重
            vo.setQty(vo.getGoodsCodes().size());

            goods = new ZjWorkGoods();
            BeanUtils.copyProperties(vo, goods);
            if (null != goods.getId()) {
                updates.add(goods);
                workGoodsId.add(goods.getId());
            } else {
                goods.setId(IdWorker.getId());
                goods.setCustAccId(custAccId);
                goods.setWorkId(workId);
                adds.add(goods);
            }
            for (OrderGoodsCodeVo goodsCodeVo : vo.getGoodsCodes()) {
                goodsCode = new ZjWorkGoodsCode();
                goodsCode.setId(IdWorker.getId());
                goodsCode.setCustAccId(custAccId);
                goodsCode.setWorkId(workId);
                goodsCode.setWorkGoodsId(goods.getId());
                goodsCode.setCodeId(goodsCodeVo.getCodeId());
                goodsCode.setCode(goodsCodeVo.getCode());
                goodsCodes.add(goodsCode);
            }
        }
        if (!adds.isEmpty()) this.saveBatch(adds);
        if (!updates.isEmpty()) this.updateBatchById(updates);
        workGoodsCodeService.deleteBatchByWorkGoodsIds(workGoodsId);
        if (!goodsCodes.isEmpty()) {
            workGoodsCodeService.saveBatch(goodsCodes);
        }
    }

    // 根据工单商品ID查询删除的信息
    @Override
    public String getDeleteInfoByIds(List<Long> ids) {
        QueryWrapper<ZjWorkGoods> wrapper = new QueryWrapper<>();
        wrapper.select("goods_id", "goods_spec_id", "qty");
        wrapper.in("id", ids);
        List<ZjWorkGoods> goodsList = this.list(wrapper);
        List<ZjWorkGoodsCode> goodsCodes = workGoodsCodeService.getByWorkGoodsIds(ids);

        List<Long> goodsIds = goodsList.stream().map(ZjWorkGoods::getGoodsId).distinct().toList();
        List<Long> goodsSpecIds = goodsList.stream().map(ZjWorkGoods::getGoodsSpecId).distinct().toList();
        List<ViewGoods> viewGoodsList = viewGoodsService.getByGoodsIdsAndGoodsSpecIds(goodsIds, goodsSpecIds);
        StringBuffer buffer = new StringBuffer("删除的工单商品：");
        ViewGoods specView = null;
        for (ZjWorkGoods vo : goodsList) {
            specView = viewGoodsList.stream().filter(vi -> Objects.equals(vi.getId(), vo.getGoodsId()) && Objects.equals(vi.getSpecId(), vo.getGoodsSpecId())).findFirst().orElse(null);
            List<String> securityCodes = goodsCodes.stream().filter(gc -> Objects.equals(gc.getWorkGoodsId(), vo.getId())).map(ZjWorkGoodsCode::getCode).toList();
            buffer.append(" 品牌：").append(specView.getBrand())
                    .append("，型号：").append(specView.getModel())
                    .append("，规格：").append(specView.getSpecName())
                    .append("，数量：").append(vo.getQty())
                    .append("，对应编码：").append(String.join("、", securityCodes));
        }
        return buffer.toString();
    }

    // 根据工单商品ID获取工单ID集合
    @Override
    public List<Long> getWorkIdByGoodIds(Long custAccId, List<Long> goodsIds) {
        return workGoodsMapper.getWorkIdByGoodIds(custAccId, goodsIds);
    }

    // 根据工单ID获取工单商品信息
    @Override
    public List<WorkGoodsExtend> getByWorkIds(List<Long> workIds) {
        if (null == workIds || workIds.isEmpty()) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjWorkGoods> wrapper = new QueryWrapper<>();
        wrapper.select("id", "work_id", "goods_id", "goods_spec_id", "qty", "buy_time", "end_time");
        wrapper.in("work_id", workIds);
        List<ZjWorkGoods> workGoods = this.list(wrapper);
        if (CollectionUtil.isEmpty(workGoods)) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjWorkGoodsCode> goodsCodeQueryWrapper = new QueryWrapper<>();
//        goodsCodeQueryWrapper.select("work_id", "work_goods_id", "code_id", "code")
        goodsCodeQueryWrapper.select("work_id", "work_goods_id", "code")
                .in("work_id", workIds);
        List<ZjWorkGoodsCode> goodsCodeList = workGoodsCodeService.list(goodsCodeQueryWrapper);
        List<Long> goodsIds = workGoods.stream().map(ZjWorkGoods::getGoodsId).distinct().toList();
        List<Long> goodsSpecIds = workGoods.stream().map(ZjWorkGoods::getGoodsSpecId).distinct().toList();
        List<ViewGoods> viewGoodsList = viewGoodsService.getByGoodsIdsAndGoodsSpecIds(goodsIds, goodsSpecIds);
        return workGoods.stream().map(go -> {
            WorkGoodsExtend extend = new WorkGoodsExtend();
            BeanUtil.copyProperties(go, extend);
            viewGoodsList.stream().filter(f -> Objects.equals(f.getId(), go.getGoodsId()) && Objects.equals(f.getSpecId(), go.getGoodsSpecId())).findFirst().ifPresent(specView -> {
                extend.setGoodsBrand(specView.getBrand());
                extend.setGoodsModel(specView.getModel());
                extend.setGoodsName(specView.getName());
                extend.setGoodsType(specView.getType());
                extend.setGoodsSpecName(specView.getSpecName());
                extend.setGoodsImage(specView.getImage());
            });
            extend.setCodes(goodsCodeList.stream().filter(f -> Objects.equals(f.getWorkGoodsId(), go.getId())).map(ZjWorkGoodsCode::getCode).toList());
            return extend;
        }).toList();
    }

    // 根据商品ID获取关联的工单商品
    @Override
    public List<ZjWorkGoods> getRelationByGoodsIds(List<Long> goodsIds) {
        if (CollectionUtil.isEmpty(goodsIds)) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjWorkGoods> wrapper = new QueryWrapper<>();
        wrapper.select("goods_id", "goods_spec_id");
        wrapper.in("goods_id", goodsIds);
        return this.list(wrapper);
    }

    // 根据商品ID获取关联的工单商品
    @Override
    public List<ZjWorkGoods> getRelationByGoodsId(Long goodsId, List<Long> goodsSpecIds) {
        QueryWrapper<ZjWorkGoods> wrapper = new QueryWrapper<>();
        wrapper.select("goods_id", "goods_spec_id");
        wrapper.eq("goods_id", goodsId);
        if (CollectionUtil.isNotEmpty(goodsSpecIds)) {
            wrapper.in("goods_spec_id", goodsSpecIds);
        }
        wrapper.last("LIMIT 10");
        return this.list(wrapper);
    }

    // 根据商品型号/名称获取工单ID
    @Override
    public List<Long> getWorkIdByGoodsName(Long custAccId, String goodsModel) {
        return workGoodsMapper.getWorkIdByGoodsName(custAccId, goodsModel);
    }

    // 根据工单ID获取工单商品
    @Override
    public List<WorkGoodsExtend> getByWorkId(Long workId) {
        List<Long> workIds = new ArrayList<>();
        workIds.add(workId);
        return getByWorkIds(workIds);
    }

}
